/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/cat.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../impl/head.h"
#include "../tools/tools.h"
#include "config.h"

namespace cat
{

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static config * config_ptr = 0;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    config::config()
    {
        // thread
        max_fast_job_thread_num = 1;
        max_slow_job_thread_num = 1;

        // heart
        show_info_interval_ms = 10 * 1000;
        heart_check_interval_ms = 1000;
        sys_heart_interval_ms = 1000;

        // net
        tcp_max_post_accept = 10;
        tcp_max_post_recv = 10;
        udp_max_post_recv = 10;
        compress_size = 512;

        // timeout
        net_timeout_ms = 60 * 1000;
        close_wait_time_s = 2;
        quit_wait_time_s = 2;
        http_timeout_s = 6;
        data_timeout_s = 6;

        // server
        webapps = "webapps";
        use_ssl = 0;
    }

    config::~config()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int config::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = xos_stl::init_obj( config_ptr );
        }

        if( 0 == ret )
        {
            ret = config::get()->load( "config.xml" );
        }

        return ret;
    }

    int config::term()
    {
        int ret = 0;

        ret = xos_stl::term_obj( config_ptr );

        return ret;
    }

    config * config::get()
    {
        return config_ptr;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // proc

    int config::load( const char * lpszFile )
    {
        int ret = 0;

        xos_xml::i_xml_node * pRoot = 0;
        xos_xml::i_xml_doc * pDoc = 0;
        char szFile[4096] = { 0 };

        if( 0 == ret )
        {
            tools::full_config_path_file( szFile, sizeof( szFile ), lpszFile );
        }

        if( 0 == ret )
        {
            ret = mgr::xos()->xml()->create_doc( &pDoc );
        }

        if( 0 == ret )
        {
            ret = pDoc->load_xml_file( szFile );
        }

        if( 0 == ret )
        {
            ret = pDoc->get_root_node( &pRoot );
        }

        if( 0 == ret )
        {
            ret = route_path( pRoot );
        }

        if( pRoot )
        {
            pRoot->release();
            pRoot = 0;
        }

        if( pDoc )
        {
            pDoc->release();
            pDoc = 0;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int config::route_path( xos_xml::i_xml_node * pNode )
    {
        int ret = 0;

        xos_xml::i_xml_node * pChild = 0;
        bool bHasChild = false;

        if( 0 == ret )
        {
            pNode->get_child_node( &pChild );
        }

        while( ( 0 == ret ) && pChild )
        {
            bHasChild = true;
            route_path( pChild );
            xos_xml::i_xml_node * pT = pChild;
            pChild = 0;
            pT->get_next_sibling_node( &pChild );
            pT->release();
            pT = 0;
        }

        if( ( 0 == ret ) && !bHasChild )
        {
            get_value( pNode );
        }

        if( pChild )
        {
            pChild->release();
            pChild = 0;
        }

        return ret;
    }

    int config::get_value( xos_xml::i_xml_node * pNode )
    {
        int ret = 0;

        char name[1024] = { 0 }, value[1024] = { 0 };

        if( 0 == ret )
        {
            pNode->get_node_value( value, sizeof( value ), 0 );
            pNode->get_node_name( name, sizeof( name ), 0 );
        }

        if( 0 == ret )
        {
            ret = get_thread( name, value );
        }

        if( 0 == ret )
        {
            ret = get_heart( name, value );
        }

        if( 0 == ret )
        {
            ret = get_net( name, value );
        }

        if( 0 == ret )
        {
            ret = get_timeout( name, value );
        }

        if( 0 == ret )
        {
            ret = get_server( name, value );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //

    int config::get_thread( const char * lpszKey, const char * lpszValue )
    {
        int ret = 1;

        if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "max_fast_job_thread_num" ) )
        {
            max_fast_job_thread_num = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "max_slow_job_thread_num" ) )
        {
            max_slow_job_thread_num = mgr::xos()->crt()->atoi( lpszValue );
        }
        else
        {
            ret = 0;
        }

        return ret;
    }

    int config::get_heart( const char * lpszKey, const char * lpszValue )
    {
        int ret = 1;

        if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "heart_check_interval_ms" ) )
        {
            heart_check_interval_ms = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "sys_heart_interval_ms" ) )
        {
            sys_heart_interval_ms = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "show_info_interval_s" ) )
        {
            show_info_interval_ms = 1000 * mgr::xos()->crt()->atoi( lpszValue );
        }
        else
        {
            ret = 0;
        }

        return ret;
    }

    int config::get_net( const char * lpszKey, const char * lpszValue )
    {
        int ret = 1;

        if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "tcp_max_post_accept" ) )
        {
            tcp_max_post_accept = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "tcp_max_post_recv" ) )
        {
            tcp_max_post_recv = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "udp_max_post_recv" ) )
        {
            udp_max_post_recv = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "compress_size" ) )
        {
            compress_size = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "net_timeout_s" ) )
        {
            net_timeout_ms = 1000 * mgr::xos()->crt()->atoi( lpszValue );
        }
        else
        {
            ret = 0;
        }

        return ret;
    }

    int config::get_timeout( const char * lpszKey, const char * lpszValue )
    {
        int ret = 1;

        if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "close_wait_time_s" ) )
        {
            close_wait_time_s = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "quit_wait_time_s" ) )
        {
            quit_wait_time_s = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "http_timeout_s" ) )
        {
            http_timeout_s = mgr::xos()->crt()->atoi( lpszValue );
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "data_timeout_s" ) )
        {
            data_timeout_s = mgr::xos()->crt()->atoi( lpszValue );
        }
        else
        {
            ret = 0;
        }

        return ret;
    }

    int config::get_server( const char * lpszKey, const char * lpszValue )
    {
        int ret = 1;

        if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "webapps" ) )
        {
            webapps = lpszValue;
        }
        else if( 0 == mgr::xos()->crt()->stricmp( lpszKey, "use_ssl" ) )
        {
            use_ssl = mgr::xos()->crt()->atoi( lpszValue );
        }
        else
        {
            ret = 0;
        }

        return ret;
    }

} // cat
